<!DOCTYPE html>
<meta charset="utf-8">
<title>Node.prototype.isEqualNode</title>
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-isequalnode">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<script>
"use strict";

test(() => {

  const doctype1 = document.implementation.createDocumentType("qualifiedName", "publicId", "systemId");
  const doctype2 = document.implementation.createDocumentType("qualifiedName", "publicId", "systemId");
  const doctype3 = document.implementation.createDocumentType("qualifiedName2", "publicId", "systemId");
  const doctype4 = document.implementation.createDocumentType("qualifiedName", "publicId2", "systemId");
  const doctype5 = document.implementation.createDocumentType("qualifiedName", "publicId", "systemId3");

  assert_true(doctype1.isEqualNode(doctype1), "self-comparison");
  assert_true(doctype1.isEqualNode(doctype2), "same properties");
  assert_false(doctype1.isEqualNode(doctype3), "different name");
  assert_false(doctype1.isEqualNode(doctype4), "different public ID");
  assert_false(doctype1.isEqualNode(doctype5), "different system ID");

}, "doctypes should be compared on name, public ID, and system ID");

test(() => {

  const element1 = document.createElementNS("namespace", "prefix:localName");
  const element2 = document.createElementNS("namespace", "prefix:localName");
  const element3 = document.createElementNS("namespace2", "prefix:localName");
  const element4 = document.createElementNS("namespace", "prefix2:localName");
  const element5 = document.createElementNS("namespace", "prefix:localName2");

  const element6 = document.createElementNS("namespace", "prefix:localName");
  element6.setAttribute("foo", "bar");

  assert_true(element1.isEqualNode(element1), "self-comparison");
  assert_true(element1.isEqualNode(element2), "same properties");
  assert_false(element1.isEqualNode(element3), "different namespace");
  assert_false(element1.isEqualNode(element4), "different prefix");
  assert_false(element1.isEqualNode(element5), "different local name");
  assert_false(element1.isEqualNode(element6), "different number of attributes");

}, "elements should be compared on namespace, namespace prefix, local name, and number of attributes");

test(() => {

  const element1 = document.createElement("element");
  element1.setAttributeNS("namespace", "prefix:localName", "value");

  const element2 = document.createElement("element");
  element2.setAttributeNS("namespace", "prefix:localName", "value");

  const element3 = document.createElement("element");
  element3.setAttributeNS("namespace2", "prefix:localName", "value");

  const element4 = document.createElement("element");
  element4.setAttributeNS("namespace", "prefix2:localName", "value");

  const element5 = document.createElement("element");
  element5.setAttributeNS("namespace", "prefix:localName2", "value");

  const element6 = document.createElement("element");
  element6.setAttributeNS("namespace", "prefix:localName", "value2");

  assert_true(element1.isEqualNode(element1), "self-comparison");
  assert_true(element1.isEqualNode(element2), "attribute with same properties");
  assert_false(element1.isEqualNode(element3), "attribute with different namespace");
  assert_true(element1.isEqualNode(element4), "attribute with different prefix");
  assert_false(element1.isEqualNode(element5), "attribute with different local name");
  assert_false(element1.isEqualNode(element6), "attribute with different value");

}, "elements should be compared on attribute namespace, local name, and value");

test(() => {

  const pi1 = document.createProcessingInstruction("target", "data");
  const pi2 = document.createProcessingInstruction("target", "data");
  const pi3 = document.createProcessingInstruction("target2", "data");
  const pi4 = document.createProcessingInstruction("target", "data2");

  assert_true(pi1.isEqualNode(pi1), "self-comparison");
  assert_true(pi1.isEqualNode(pi2), "same properties");
  assert_false(pi1.isEqualNode(pi3), "different target");
  assert_false(pi1.isEqualNode(pi4), "different data");

}, "processing instructions should be compared on target and data");

test(() => {

  const text1 = document.createTextNode("data");
  const text2 = document.createTextNode("data");
  const text3 = document.createTextNode("data2");

  assert_true(text1.isEqualNode(text1), "self-comparison");
  assert_true(text1.isEqualNode(text2), "same properties");
  assert_false(text1.isEqualNode(text3), "different data");

}, "text nodes should be compared on data");

test(() => {

  const comment1 = document.createComment("data");
  const comment2 = document.createComment("data");
  const comment3 = document.createComment("data2");

  assert_true(comment1.isEqualNode(comment1), "self-comparison");
  assert_true(comment1.isEqualNode(comment2), "same properties");
  assert_false(comment1.isEqualNode(comment3), "different data");

}, "comments should be compared on data");

test(() => {

  const documentFragment1 = document.createDocumentFragment();
  const documentFragment2 = document.createDocumentFragment();

  assert_true(documentFragment1.isEqualNode(documentFragment1), "self-comparison");
  assert_true(documentFragment1.isEqualNode(documentFragment2), "same properties");

}, "document fragments should not be compared based on properties");

test(() => {

  const document1 = document.implementation.createDocument("http://example.org", "example");
  const document2 = document.implementation.createDocument("http://example.org", "example");

  assert_true(document1.isEqualNode(document1), "self-comparison");
  assert_true(document1.isEqualNode(document2), "another empty XML document");

  const htmlDoctype = document.implementation.createDocumentType("html", "", "");
  const document3 = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", htmlDoctype);
  document3.documentElement.appendChild(document3.createElement("head"));
  document3.documentElement.appendChild(document3.createElement("body"));
  const document4 = document.implementation.createHTMLDocument();
  assert_true(document3.isEqualNode(document4), "default HTML documents, created different ways");

}, "documents should not be compared based on properties");

test(() => {
  const parentA = document.createElement("foo");
  const parentB = document.createElement("foo");

  parentA.appendChild(document.createElement("p"));
  assert_false(parentA.isEqualNode(parentB));
  parentB.appendChild(document.createElement("p"));
  assert_true(parentA.isEqualNode(parentB));

  parentA.firstChild.appendChild(document.createTextNode("data"));
  assert_false(parentA.isEqualNode(parentB));
  parentB.firstChild.appendChild(document.createTextNode("data"));
  assert_true(parentA.isEqualNode(parentB));
}, "node equality testing should test descendant equality too");
</script>
